/************************************************
编写：邬畏畏
blogs:www.cnblogs.com/wsoft
wui:www.flybirdsoft.com/wui
前端模板引擎
功能：模板处理
*************************************************/
(function(win){

var template = function(options){
	this._startSymbol = "\{\{";
	this._endSymbol = "\}\}";
	this.templateElement = {};
	this.contentNode = null;
	options.beforeCreate&&options.beforeCreate.call(this); /*time life (1)*/
	this.repeat(options);
	options.mounted&&options.mounted.call(this); /*time life (3)*/
};

template.useES5GetSet = true;  //if use es5 get set method
template.prefix = "_";         //当使用es5 get set时,prefix is "_"

template.prototype.useEs5DataBind = function(bool){
	template.useES5GetSet = bool;
	if(!bool)
	{
		template.prefix = "";
	}
}

template.prototype.startSymbol=function(symbol){
	var _symbol="",i;
	var regx="\^$*+?{}[]|.";
	for(i=0;i<symbol.length;i++)
	{
		if(regx.indexOf(symbol.substr(i,1))>=0)
		{
			_symbol = _symbol + '\\' ;
		}
		_symbol = _symbol + symbol.substr(i,1);
	}
	this._startSymbol = _symbol;
};
template.prototype.endSymbol=function(symbol){
	var _symbol="",i;
	var regx="\^$*+?{}[]|.";
	for(i=0;i<symbol.length;i++)
	{
		if(regx.indexOf(symbol.substr(i,1))>=0)
		{
			_symbol = _symbol + '\\' ;
		}
		_symbol = _symbol + symbol.substr(i,1);
	}
	this._endSymbol = symbol;
};

/*模板函数入口*/
template.prototype.repeat = function(options){
	/*
	options={
		data:data,
		repeatElement|repeatId:"",
		template:"", 
		render:function(object){
			object.index,object.item.field
			return {"field":"xxx"}
		},
		count:n,
		type : "cover|append|insert",
		onload : function(){},
		loadBefore:function(){}
	}

	可选参数：template,render,count,type(默认cover),onload
	*/
	this.options = options;
	if(options.data==undefined)
	{
		throw new Error("参数名称不对,参数是{},缺少data");
		return;
	}
	if((options.repeatId==undefined&&options.repeatElement==undefined))
	{
		throw new Error("参数名称不对,参数是{},缺少repeatElement或repeatId");
		return;
	}

	var tmpl={string:""},all="";            /*tmpl=依据模板替换后的数据,all=全部替换的数据*/
	var data =[];                           /*存储传入的数据，list*/
	var i,j,len=0,item,subItem;               /*item=data中的每一行数据 , len=data数组长度*/
	var v,subv,jsonStr="";                  /*v,subv存储JOSN中的key; jsonStr存储JSON的表达式形式如：title.sum*/
	var target;                             /*存储模板DOM对象*/
	var nextNode=null,lastNode=null;        /*用于parent.insertBefore*/
	var parent;                             /*模板的父节点*/
	var fun=function(){},result,v;          /*fun是render回调函数*/
	
	var resultObject={};
	var json={};
	var node=null;                          /*插入的节点元素*/
	
	var strV                                /*即页面字段值例如：${title}*/,reg/*strV的正则表达式*/;
	var attrValue="";                      /*repeatId元素上的遍历属性值*/
	
	target = options.repeatElement;
	parent = target.parentNode;

	if(options.type==undefined ||(options.type!=undefined && options.type=="cover"))
	{
		this.deleteNode(target);              /*删除所有节点*/
	}
	
	if(options.template==undefined)
	{
		options.template = target.innerHTML;
	}
	
	if(options.data.length==undefined)
	{
		len=1;
		data[0]=options.data;
	}
	else
	{
		len=options.data.length;
		data=options.data;
	}
	
	if(options.count!=undefined)
	{
		if(options.count<=len)
		{
			len = options.count;
		}
	}
	
	if(options.render!=undefined)
	{
		fun=options.render||options.onrender;
	}

	nextNode = target;
	lastNode = parent.lastChild;

	for(i=len-1;i>=0;i--)  /*节点是到的插入才是顺序显示*/
	{
		item = data[i];

		resultObject={index:i,item:data[i]};

		result = fun.call(this,resultObject);           /*执行回调函数*/

		node = document.createElement(target.nodeName); /*创建插入的节点*/

		for(j=0;j<target.attributes.length;j++)         /*遍历repeat元素上的属性*/
		{
			attrValue = target.attributes.item(j).value;
			for(v in result)
			{
				strV = this._startSymbol+v+this._endSymbol;
				reg = new RegExp(strV,"g");
				attrValue = attrValue.replace(reg,result[v]);
			}
			for(v in item)
			{
				strV = this._startSymbol+v+this._endSymbol;
				reg = new RegExp(strV,"g");	
				attrValue = attrValue.replace(reg,item[v]);
			}
			node.setAttribute(target.attributes.item(j).name , attrValue);			
		}

		tmpl.string=options.template;

		for(v in result)
		{
			if(typeof(result[v])!="object")
			{
				strV = this._startSymbol+v+this._endSymbol;
				reg = new RegExp(strV,"g");
				//tmpl.string = tmpl.string.replace(reg,result[v]); //code good
				tmpl.string = tmpl.string.replace(reg,result[v].replace(/,/g,"")); /*解决外部使用 map()函数返回逗号问题*/
			}
			else
			{
				this.getScope(result,v,tmpl);
			}
			/*
			strV = this._startSymbol+v+this._endSymbol;
			reg = new RegExp(strV,"g");	
			tmpl.string = tmpl.string.replace(reg,result[v]);
			*/
		}
		for(v in item)
		{
			if(typeof(item[v])!="object")
			{
				strV = this._startSymbol+v+this._endSymbol;
				reg = new RegExp(strV,"g");
				tmpl.string = tmpl.string.replace(reg,item[v]);
			}
			else
			{
				this.getScope(item,v,tmpl);
			}
		}
		
		node.innerHTML = tmpl.string;
		if(options.type!=undefined&&options.type=="append")
		{
			while(lastNode!=null)
			{
				if(lastNode.nodeType==1 && lastNode.getAttribute("templateItem")=="templateItem")
				{
					break;
				}
				lastNode = lastNode.previousSibling;
			}
			parent.insertBefore(node,lastNode.nextSibling);
			node.style.display="";
			node.setAttribute("templateItem","templateItem");
			node.setAttribute("templateItem-index",i);   /*为DOM列表生成顺序索引,base 0*/
			node = lastNode;
		}
		else
		{
			parent.insertBefore(node,nextNode.nextSibling);
			node.style.display="";
			node.setAttribute("templateItem","templateItem");
			node.setAttribute("templateItem-index",i);
		}

		options.onEvent&&options.onEvent(node);

	} /*end for 模板渲染完毕*/

	target.style.display="none";

	options.created&&options.created.call(this); /*time life (2)*/

	console.log("**",data)
	var innerData = this.copyUserData(data); /*把数据进行深拷贝*/
	this.innerData = innerData;
	window.innerData = innerData;
	this.extendData(data); /*便利所有属性并加下划线*/
	this.es5GetSet(options);
	/*
	return new this.ModelView({
		innerData : innerData,
		data : data,
		target : target,
		parentNode : parent
	});
	*/

}/*end function repeat*/


/*
TYPE: API
开发着调用的方法
*/
template.prototype.render = function(){
	this.repeat(this.options);
}

/*获取JSON的对象形式*/
template.prototype.getScope = function(item,v,tmpl,scopeStr){
	var jsonStr="",subv,subItem, strV, reg;
	subItem = item[v];
	if(typeof(subItem)=="object")
	{
		if(scopeStr==undefined)
		{
			jsonStr = v;
		}
		else
		{
			jsonStr = scopeStr;
		}
		for(subv in subItem)
		{
			jsonStr += "."+subv;
			if(typeof(subItem[subv])=="object")
			{
				this.getScope(subItem,subv,tmpl,jsonStr);
				return;
			}
			strV = this._startSymbol+jsonStr+this._endSymbol;
			reg = new RegExp(strV,"g");
			tmpl.string = tmpl.string.replace(reg , subItem[subv]);
		}
	}
	return ;
}

/*
使用于ea5 get set 后的属性
注意:再使用es5的get set 之前 template.extendData方法
把template.repeat方法中参数data属性进行复制加下划线
*/
template.prototype.getES5Scope = function(item,v,tmpl,scopeStr){
	var jsonStr="",subv,subItem, strV, reg;
	subItem = item[v];
	//console.log("scope:",scopeStr);
	if(typeof(subItem)=="object")
	{
		if(scopeStr==undefined)
		{
			jsonStr = v;
		}
		else
		{
			jsonStr = scopeStr;
		}
		for(subv in subItem)
		{
			jsonStr += "."+subv;
			if(typeof(subItem[subv])=="object")
			{
				this.getES5Scope(subItem,subv,tmpl,jsonStr);
				return;
			}
			strV = this._startSymbol+jsonStr+this._endSymbol;
			reg = new RegExp(strV,"g");
			tmpl.string = tmpl.string.replace(reg , subItem[template.prefix + subv]);
		}				
	}
	return ;
}


/*
用于es5的get和set
给所有属性加下划线
*/
template.prototype.extendData = function(data){
	var i,v,item;
	var len = data.length;
	var copyArray = function(arr){ /* 废弃 */
		var newArr,i,len;
		len = arr.length;
		newArr = [];
		for(i=0;i<len;i++)
		{
			newArr.push(arr[i]);
		}
		return newArr;
	}

	var deepCopy = function(item){
		var v;

		for(v in item)
		{

			if(typeof item[v] === 'object')
			{
				//item["_"+v] = (item[v].constructor === Array) ? [] : {};
				//item["_"+v] = deepCopy(item[v]);
				deepCopy(item[v]);
			}
			else if(item[v].constructor == Array) /* never use */
			{
				item["_"+v] = copyArray(item[v]);
			}
			else
			{
				item["_"+v] = item[v];
			}
			
		}
		return item;
	}

	for(i=0;i<len;i++)
	{
		item = data[i];
		deepCopy(item);
	}
	
	console.log("extendData:",data);
}

/*
用户es5的get和set
深拷贝数据;
把用户数据拷贝
*/
template.prototype.copyUserData = function(data){
	var i,v,item;
	var len = data.length;
	var newData = []; /*最终生成的 用户数据*/

	var deepCopy = function(item,_newItem){
		var v,newItem = _newItem || {};

		for(v in item)
		{
			if(typeof(item[v]) == 'object')
			{
				newItem[v] = (item[v].constructor === Array) ? [] : {};
				newItem[v] = deepCopy(item[v],newItem[v]);
			}
			else
			{
				newItem[v] = item[v];
			}
		}
		return newItem;	
	}

	for(i=0;i<len;i++)
	{
		item = data[i];
		newData.push(deepCopy(item));
	}
	console.log("newData",newData);
	return newData;
}



/*删除DOM节点*/
template.prototype.deleteNode=function(target){
	var node = target.nextSibling;
	if(node ==null)/*如果options.data is [] ,node is null*/
	{
		return;
	}
	var nextNode,ife;
	try
	{
		ife = (node.nodeType==1&&node.getAttribute("templateItem")=="templateItem")||node.nodeType!=1;
	}
	catch(e)
	{
		return;
	}
	while(node!=null)
	{
		nextNode = node.nextSibling;
		if(ife)
		{
			node.parentNode.removeChild(node);
		}
		node = nextNode;
		if(node==null)/*如果没有要删除的节点推出循环*/
		{
			break;
		}
		ife = (node.nodeType==1&&node.getAttribute("templateItem")=="templateItem");
	}
	return;
	for(i=0;i<len;i++)
	{
		if(childNodes[i].nodeType==1&&childNodes[i].getAttribute("templateItem")=="templateItem")
		{
			parentNode.removeChild(childNodes[i]);
		}
	}
}


/*
set get set method 数据驱动
*/
template.prototype.es5GetSet = function(options){
	var th =this;
	var len = options.data.length;
	var i ,j  , v , item , result;
	var th = this;
	var _scopeObj;
	if(Object.defineProperty==undefined) /*不支持ES5新特性*/
	{
		return;
	}

	var _defineProperty = function(object,key,index){
		Object.defineProperty(object , key, {
		 	get: function() {
		 		return this["_"+key];
		    },
		 	set: function(o) {
		     	this["_"+key] = o;
		     	th.viewPage(index);
		    }
		});
	}

	var _iteration = function(item,index){
		for(v in item)
		{
			if(v.indexOf("_")>=0)
			{
				continue;
			}
			
			if(typeof(item[v])!="object")
			{
				_defineProperty(item,v,index);
			}
			else
			{
				_iteration(item[v],index);
			}

		}
	}
	//console.log("DATA",len)
	if(!!!len)
	{
		item = options.data;
		_iteration(item,0);
		return;
	}

	for(i=0;i<len;i++)
	{
		let n = i;
		item = options.data[i];
		_iteration(item,i);
	}
}

/*
对Array增加监听,需要在初始化template时调用 ***未完全实现***
*/
var monitorArray = function(arrayData,optionsDataIndex){
	var arrayPush = {};
	arrayPush.optionsDataIndex = optionsDataIndex;
	var methodsToPatch = [
		'push',
		'pop',
		'shift',
		'unshift',
		'splice',
		'sort',
		'reverse',
		'filter',
		'map',
		'every',
		'some',
		'reduce',
		'split',
	];
	methodsToPatch.forEach(method =>{
	    var original = Array.prototype[method];
	    arrayPush[method] = function() {
	        // this 指向可通过下面的测试看出
	        console.log(this);
	        return original.apply(this, arguments)
	    };	
	});

	arrayData.__proto__ = arrayPush;
}

/*
渲染页面上某个DOM数据
*/
template.prototype.viewPage = function(index){
	this.repeatToSingleNode(index);
	this.options.stateChange&&this.options.stateChange(this.options.data[index]); /*time life (4)*/
}

/*
更新页面某个DOM数据或添加新的DOM
*/
template.prototype.repeatToSingleNode = function(itemIndex,isNew){
	/*
	参数:itemIndex is this.data index
	*/
	//console.log(itemIndex);
	var node ,v ,j;
	var target = this.options.repeatElement;
	var tmpl = {string:""};
	var item = this.options.data[itemIndex]; /*需要给你关心的数据*/
	if(this.options.data.constructor == Array)
	{
		item = this.options.data[itemIndex];
	}
	else if(this.options.data.constructor == Object)
	{
		item = this.options.data;
	}
	console.log("item=>",item);
	var resultObject,result;/*render method callback use*/
	var attrValue,reg,strV;
	tmpl.string = target.innerHTML;  /*模板内容*/

	var fun=this.options.render||this.options.onrender; /*执行repeat()函数中参数的render,render is function*/

	if(isNew!=undefined&&isNew)
	{
		node = document.createElement(target.nodeName);
	}
	else
	{
		node = this.findNode(itemIndex);
	}

	resultObject={index : itemIndex , item : item};
	result = fun.call(this,resultObject);  /*执行回调函数*/

	for(j=0;j<target.attributes.length;j++)         /*遍历repeat元素上的属性*/
	{
		attrValue = target.attributes.item(j).value;
		for(v in result)
		{
			strV = this._startSymbol+v+this._endSymbol;
			reg = new RegExp(strV,"g");				
			attrValue = attrValue.replace(reg,result[v]);
		}
		for(v in item)
		{
			strV = this._startSymbol+v+this._endSymbol;
			reg = new RegExp(strV,"g");	
			attrValue = attrValue.replace(reg,item[this.prefix + v]);
		}
		node.setAttribute(target.attributes.item(j).name , attrValue);
	}

	for(v in result)
	{
		if(typeof(result[v])!="object")
		{
			strV = this._startSymbol+v+this._endSymbol;
			reg = new RegExp(strV,"g");
			//tmpl.string = tmpl.string.replace(reg , result[v]);
			if(!!result[v])
			{
				tmpl.string = tmpl.string.replace(reg , result[v].replace(/,/g,""));
			}
		}
		else
		{
			this.getES5Scope(result,v,tmpl);
		}
	}
	for(v in item)
	{
		if(typeof(item[v])!="object")
		{
			strV = this._startSymbol+v+this._endSymbol;
			reg = new RegExp(strV,"g");
			//tmpl.string = tmpl.string.replace(reg , item[template.prefix + v]);
			if(!!item[template.prefix + v])
			{
				tmpl.string = tmpl.string.replace(reg , item[template.prefix + v].replace(/,/g,""));
			}
		}
		else
		{
			this.getES5Scope(item,v,tmpl);
		}
	}
	node.innerHTML = tmpl.string;
	node.style.display = "";
	return node;
}

/*通过索引查找DOM段素*/
template.prototype.findNode = function(itemIndex){
	var parentNode = this.options.repeatElement.parentNode;
	var i , index = -1 , isStart = false;
	var childs = parentNode.childNodes;
	var len = childs.length;
	for(i=0;i<len;i++)
	{

		if(childs[i].nodeType == 1 && childs[i].getAttribute("templateitem")=="templateItem")
		{
			index++;
		}
		if(index==itemIndex)
		{
			return childs[i];
		}
	}
	return null;
}




/*
***************************
模型对象
功能:
template.repeat return 的对象;
用来控制页面DOM和data
***************************
*/
template.ModelView = function(options){
	/* autoReview 属性(外部控制)是否通过es5的get,set自动更新页面*/
	this.autoReview = true;

	this.innerData = options.innerData;
	this.data = options.data;
	this.parentNode = options.parentNode;
	this.target = options.target;
	this.changedIndexs = [];
	/*
	this.row = {...}; 用于repeatToSingleNode()函数
	this.changedIndexs = []; 存放数据被改变的索引
	*/
	if(template.useES5GetSet)
	{
		this.es5GetSet();
	}
}

/*通过索引查找DOM段素*/
template.ModelView.prototype.findNode = function(itemIndex){
	var i , index = 0 , isStart = false;
	var childs = this.parentNode.childNodes;
	var len = childs.length;
	for(i=0;i<len;i++)
	{
		if(this.target == childs[i])
		{
			index = 0;
			isStart = true;
		}
		if(childs[i].nodeType == 1)
		{
			index++;
		}
		if(isStart && index == itemIndex+2)
		{
			return childs[i];
		}
	}
	return null;
}

/*
更新页面某个DOM数据或添加新的DOM
*/
template.ModelView.prototype.repeatToSingleNode = function(itemIndex,isNew){
	/*
	参数:itemIndex is this.data index
	*/
	var node ,v ,j;
	var target = this.target;
	var tmpl = {string:""};
	var item = this.row; /*需要给你关心的数据*/
	var attrValue,reg,strV;
	tmpl.string = target.innerHTML;  /*模板内容*/
	if(isNew!=undefined&&isNew)
	{
		node = document.createElement(target.nodeName);
	}
	else
	{
		node = this.findNode(itemIndex);
	}
	for(j=0;j<target.attributes.length;j++)         /*遍历repeat元素上的属性*/
	{
		attrValue = target.attributes.item(j).value;
		for(v in item)
		{
			strV = template._startSymbol+v+template._endSymbol;
			reg = new RegExp(strV,"g");	
			attrValue = attrValue.replace(reg,item[template.prefix + v]);
		}
		node.setAttribute(target.attributes.item(j).name , attrValue);
	}
	for(v in item)
	{
		if(typeof(item[v])!="object")
		{
			strV = template._startSymbol+v+template._endSymbol;
			reg = new RegExp(strV,"g");
			tmpl.string = tmpl.string.replace(reg , item[template.prefix + v]);
		}
		else
		{
			template.getES5Scope(item,v,tmpl);
		}
	}
	node.innerHTML = tmpl.string;
	node.style.display = "";
	return node;
}

/*
根据条件查找匹配数据;
返回值:返回被查找的node节点在this.data中的位置,从0开始
*/
template.ModelView.prototype.doCondition = function(condition){
	/*
	condition,data is json
	condition = {"app.title.num":"100"}
	返回值:return -1 表示没有找到匹配的数据,return >=0 表示找到匹配的数据
	注意  :
	*/

	var v,i,j;
	var len = this.data.length;
	var data = this.data;
	var item;
	var keyArr , value;
	var isUndefined = false;
	var isFound = false;      /*根据参数condition找到匹配的数据*/
	var isFail = false;       /*如果isFail=true表示最终没找到*/
	var itemIndex = -1;

	for(v in condition)
	{
		keyArr = v.split(".");
		value = condition[v];
		isUndefined = false;
		isFound = false;

		for(i=0;i<len;i++)
		{
			item = data[i];
			for(j=0;j<keyArr.length;j++)
			{
				item = item[keyArr[j]];
				if(item==undefined)
				{
					isUndefined = true;
					break;
				}
			}

			if(isUndefined)
			{
				break;
			}
			else if(item == value)
			{
				isFound = true;
				itemIndex = i;
				break;
			}
			else
			{
				isFound = false;
			}
		}/*end for i*/
		if(!isFound)
		{
			break;
		}
	}

	if(isFound)
	{
		return itemIndex; /*itemIndex是在this.data中的位置,从0开始*/
	}
	else
	{
		return -1;
	}
}


/*
类型:接口
功能:更新页面数据
*/
template.ModelView.prototype.update = function(condition,row,callback){
	/*
	condition,data is json
	condition = {"app.title.num":"100"}
	*/
	this.row = row;  /*repeatToSingleNode()用到this.row*/

	var itemIndex;
	itemIndex = this.doCondition(condition);
	if(itemIndex!=-1)
	{
		this.repeatToSingleNode(itemIndex);
		this.data[itemIndex] = row;
	}
	callback.call(this,itemIndex==-1?false:true);
	/*
	callback(p);返回一个参数为bool型,该参数说明更新是否成功
	*/
}

/*
类型:接口
功能:删除数据
*/
template.ModelView.prototype.delete = function(condition,callback){
	var itemIndex;
	var node;
	itemIndex = this.doCondition(condition);
	node = this.findNode(itemIndex);
	node.parentNode.removeChild(node);
	this.data.splice(itemIndex,1);
	if(callback!=undefined)
	{
		callback.call(this,itemIndex==-1?false:true);
	}
}

/*
类型:接口
功能:删除数据
*/
template.ModelView.prototype.deleteIndex = function(itemIndex,callback){
	/*
	itemIndex is this.data index
	*/
	var node;
	node = this.findNode(itemIndex);
	node.parentNode.removeChild(node);
	this.data.splice(itemIndex,1);
	if(callback!=undefined)
	{
		callback.call(this,itemIndex==-1?false:true);
	}
}

/*
类型:接口
功能:添加数据
*/
template.ModelView.prototype.add = function(row,callback){
	var itemIndex;
	var node,prevNode = null;
	this.row = row;
	node = this.repeatToSingleNode(-1,true);
	prevNode = this.parentNode.lastChild;
	while(prevNode!=null)
	{
		if(prevNode.nodeType==1 && prevNode.getAttribute("templateItem")=="templateItem")
		{
			break;
		}
		prevNode = prevNode.previousSibling;
	}
	this.parentNode.insertBefore(node,prevNode.nextSibling);
	this.data.push(row);
	if(callback!=undefined)
	{
		callback.call(this);
	}
}

/*
类型:接口
功能:插入数据
*/
template.ModelView.prototype.insert = function(rowIndex,row,callback){
	/*
	rowIndex is this.data index
	*/
	var node , posNode = null ,i;
	this.row = row;
	node = this.repeatToSingleNode(-1,true);
	posNode = this.target.nextSibling;
	for(i=0;i<rowIndex;i++)
	{
		posNode = posNode.nextSibling;
	}
	this.parentNode.insertBefore(node,posNode);
	this.data.splice(rowIndex,0,row);
	if(callback!=undefined)
	{
		callback.call(this);
	}
}

template.ModelView.prototype.destroy = function(){
	this.data.length = 0;
	this.parentNode = null;
	this.target = null;
}



/*
es5 新特性应用 set get,给数据对象增加get和set方法
功能:当外界改变data数组中对象的某个值,能记录下
*/
template.ModelView.prototype.es5GetSet = function(){
	var len = this.data.length;
	var i ,j  , v , item , result;
	var th = this;
	var _scopeObj;
	if(Object.defineProperty==undefined) /*不支持ES5新特性*/
	{
		return;
	}
	this._scopeAr = [];
	var isObject = function(v,obj,item){
		/*v is key; obj is value*/
		var vv;
		var object;
		if(typeof(obj)=="object")
		{
			th._scopeAr.push(v);
			for(vv in obj)
			{
				if(typeof(obj[vv])=="object")
				{
					return isObject(vv,obj[vv]);
				}
				else
				{
					th._scopeAr.push(vv);
					return {
						attrName : vv,
						scope : th._scopeAr
					};
					return vv;
				}	
			}
		}
		else
		{
			return {
				attrName : v,
				scope : null 
			};/*here obj is not object*/
			return v;
		}

	}

	for(i=0;i<len;i++)
	{
		let n = i;
		item = this.data[i];
		this._scopeAr.length = 0;
		for(v in item)
		{
			if(v.indexOf("_")>=0)
			{
				continue;
			}
			//let result = isObject(v,item[v]);
			
			if(typeof(item[v])!="object")
			{
				Object.defineProperty(item , v, {
				 	get: function() {
				 		return this["_"+v];
				    },
				 	set: function(o) {
				     	this["_"+v] = o;
				     	th.changedIndexs.push(n);
				     	th.autoReview && th.viewPage(n);
				    },
				    enumerable: true,  
    				configurable: true
				});
				continue;
			}
			
			if(this._scopeAr.length!=0)
			{
				_scopeObj = item;
				for(j=0;j<this._scopeAr.length;j++)
				{
					if(v.indexOf("_")>=0)
					{
						//continue;
					}
					

					var attrName = this._scopeAr[j];
					
					Object.defineProperty(_scopeObj, attrName, {
						get: function() {
					    	return this["_"+attrName];
					    },
						set: function(o) {
					    	this["_"+attrName] = o;
					    	th.changedIndexs.push(n);
					    	th.autoReview && th.viewPage(n);
					    }
					});
					_scopeObj = _scopeObj[this._scopeAr[j]];
				}
			}
		}
	}
}



template.ModelView.prototype.viewPage = function(n){
	var i,len;
	this.row = this.data[n];
	this.repeatToSingleNode(n);
	this.changedIndexs.length = 0;
}

/*
根据es5 get set 新功能 改变的值,通过refresh更新到页面上
*/
template.ModelView.prototype.refresh = function(){
	var i,len;
	len = this.changedIndexs.length;
	for(i=0;i<len;i++)
	{
		this.row = this.data[this.changedIndexs[i]];
		this.repeatToSingleNode(this.changedIndexs[i]);
	}
	this.changedIndexs.length = 0;
}


/*on()方法还没有写完*/
template.ModelView.prototype.on = function(eventName,target,f){
	/*
	参数说明:
	eventName is string;target is string example("div a")
	*/
	var fun;
	var queryAr,queryArLen=0;
	var th = this;
	var childs = this.parentNode.childNodes;
	if(arguments.length==2)
	{
		fun = target;
	}
	else if(arguments.length==3)
	{
		queryAr = target.split(" ");
		queryArLen = queryAr.length;
		fun = f;
	}

	this.parentNode.addEventListener(eventName,function(e){
		var target = e.target||e.srcElement;
		if(queryArLen==0)
		{
			if(target.getAttribute("templateitem") == "templateItem" || th.parentNode.contains(target))
			{
				fun.call(th,e);
			}
		}
	},false);

	var i_n = 0;
	for(i=0;i<childs.length;i++)
	{
		if(childs[i].nodeType == 1 && childs[i].getAttribute("templateitem") == "templateItem")
		{
			childs[i].addEventListener(eventName,function(i_n,targetParent){
				return function(e){
					var target = e.target||e.srcElement;
					if(isTarget(queryAr,target,targetParent))
					{
						th.item = th.data[targetParent.getAttribute("templateitem-index")];
						th.itemIndex = targetParent.getAttribute("templateitem-index");
						fun.call(th,e);
					}					
				}
			}(i_n,childs[i]),false);
			i_n++;	
		}
	}
	/*判断是否符合on()中第二个参数*/
	var isTarget = function(ar,target,targetParent){
		/*ar is param target array*/
		var i=0;
		var len = ar.length, count = 0;
		var isContinue = false;
		i = len - 1;

		while(targetParent.contains(target))
		{
			if(ar[i].indexOf(".")==0)/* is .xxx*/
			{
				if(target.className.indexOf(ar[i].replace(".",""))>=0)
				{
					count++;
					i--;
				}
			}
			else if(ar[i].indexOf(".")>0) /*is xx.yy example div.red*/
			{

			}
			else
			{
				if(target.nodeName==ar[i].toUpperCase())
				{
					count++;
					i--;
				}
			}
			if(i<0)
			{
				break;
			}
			target = target.parentNode;
		}

		if(count == len)
		{
			return true;
		}
		else
		{
			return false;
		}

	}
}


win.T=win.wTemplate=template;

})(window);

/*

更新数据
$("#btn_update").click(function(){
    modelView.update({
        "numbers.app.count":"300",
        "title":"我的应用3"
        },
        {
            title:"xxx",
            url:"WUI",
            numbers:
            {
                app:{count:"00"}
            }
        },
        function(isOK){
            //isOK=true表示更新成功
            alert(isOK);
        }
    );
});

删除数据
$("#btn_delete").click(function(){
    modelView.delete({
        "numbers.app.count":"500",
        "title":"我的应用2"
        },
        function(){
            alert('删除成功');
        }
    );
});

添加数据
$("#btn_add").click(function(){
    modelView.add({
            title:"newTitle",
            url:"www.new.com",
            numbers:
            {
                app:{count:"90"}
            }
        },
        function(){
            alert('添加成功');
        }
    );
});

插入数据
$("#btn_insert").click(function(){
    modelView.insert(1,{
            title:"newTitle",
            url:"www.new.com",
            numbers:
            {
                app:{count:"90"}
            }
        },
        function(){
            alert('添加成功');
        }
    );
});


-------------------------
template.4.0实现了数据驱动

data = [
    {
        title:"我的应用1",
        url:"www.cnblogs.com/wsoft1",
        numbers:
        {
            app:{count:"100"}
        }
    },
    {
        title:"我的应用2",
        url:"www.cnblogs.com/wsoft2",
        numbers:
        {
            app:{count:"100"}
        }
    }
];

wTemplate.repeat({
    repeatElement : $(".app-myapp")[0],
    data : data,
    onloadBefore : function(){
        console.log("load before");
    },
    onload : function(){
        console.log("loaded");
    },
    onStateChange:function(item){
        console.log(item);
    }
});

修改数据后页面元素更新
$("#btn_data").on("click",function(){
    data[1].title = "qqwewrw";
    data[1].url = "myurl";
    data[0].numbers.app.count = 90;
});
*/